/** Implementation of Word Class.
 * @file 
 * @author Jeremy Schultz
 */
#include "Word.h"


using namespace std;

//-----------------------------------------------------------------------------
// Constructor
Word::Word() : Token(Token::ID)	{
	lex = "";
	offset = 0;
	level = 0;
	data = NULL;
}
//-----------------------------------------------------------------------------
// Constructor
Word::Word(string _lex) : Token(Token::ID)	{
	lex = _lex;
	offset = 0;
	level = 0;
	data = NULL;
}
//-----------------------------------------------------------------------------
// Constructor
Word::Word(string _lex, TokenType _type) : Token(_type) {
	lex = _lex;
	offset = 0;
	level = 0;
	data = NULL;
}

//-----------------------------------------------------------------------------
// Getter - Lex
string Word::Lex()	{
	return lex;
}

//-----------------------------------------------------------------------------
// Setter - Lex
void Word::setLex(string _lex)	{
	lex = _lex;
}

//-----------------------------------------------------------------------------
// Getter - Level
int Word::Level()	{
	return level;
}

//-----------------------------------------------------------------------------
// Setter - Level
void Word::setLevel(int _level)	{
	level = _level;
}

//-----------------------------------------------------------------------------
// Getter - Offset
int Word::Offset()	{
	return offset;
}

//-----------------------------------------------------------------------------
// Setter - Offset
void Word::setOffset(int _offset)	{
	offset = _offset;
}


//-----------------------------------------------------------------------------
// Getter - Data
WordData* Word::Data()	{
	return data;
}


//-----------------------------------------------------------------------------
// Setter - data
void Word::setData(WordData* _data)	{
	data = _data;
}

//-----------------------------------------------------------------------------
// Setter - data (DataType)
void Word::setData(WordData::DataType type)	{
	if (type == WordData::NUMBER) {
		data = new DataNumber();
	}else if (type == WordData::BOOL) {
		data = new DataBool();
	}else if (type == WordData::ID) {
		data = new DataID();
	}else {
		data = new WordData(type);
	}
}

//-----------------------------------------------------------------------------
// Setter - data (Array)
void Word::setData(WordData::DataType type, int size)	{
	if (type == WordData::NUMBER) {
		data = new DataNumber(size, true);
	}else if (type == WordData::BOOL) {
		data = new DataBool(size);
	
	// This should not happen 
	}else {
		data = new WordData(WordData::ERROR);
	}
}


//-----------------------------------------------------------------------------
// Setter - data (Number)
void Word::setData(int value)	{
	data = new DataNumber(value);
}


//-----------------------------------------------------------------------------
// Setter - data (Bool)
void Word::setData(bool value)	{
	data = new DataBool(value);
}

//-----------------------------------------------------------------------------
// Setter - data (ID)
void Word::setData(string word)	{
	data = new DataID(word);
}


//-----------------------------------------------------------------------------
// convert Word to string
string Word::toString()	{
	stringstream ss;

	ss << Token::toString();
	ss << " level: " << level;
	ss << " offset: " << offset;
	ss << " lex: " << lex;

	if (data != NULL) {
		if (data->Type() == WordData::NUMBER) {
			ss << " data: [" << DATANUMBER(data)->toString() << "]";
		}else if (data->Type() == WordData::BOOL) {
			ss << " data: [" << DATABOOL(data)->toString() << "]";
		}else if (data->Type() == WordData::ID) {
			ss << " data: [" << DATAID(data)->toString() << "]";
		}else if (data->Type() == WordData::PROCEDURE) {
			ss << " data: [" << DATAPROCEDURE(data)->toString() << "]";
		}else {
			ss << " data: [" << data->toString() << "]";
		}
	}

	return ss.str();
}

//-----------------------------------------------------------------------------
// Define all the Keywords for PL
const string* Word::Keywords()	{
	static const string keys[] = {
		"begin", 
		"end", 
		"const", 
		"array", 
		"integer", 
		"Boolean", 
		"proc", 
		"skip", 
		"read", 
		"write", 
		"call", 
		"if", 
		"do", 
		"fi", 
		"od", 
		"false", 
		"true",
		""
	};

	return keys;
}

